
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>协程与任务 &#8212; Python 3.7.3 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.3 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="流" href="asyncio-stream.html" />
    <link rel="prev" title="asyncio --- 异步 I/O" href="asyncio.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/library/asyncio-task.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    <script type="text/javascript" src="../_static/switchers.js"></script>
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="asyncio-stream.html" title="流"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="asyncio.html" title="asyncio --- 异步 I/O"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <span class="language_switcher_placeholder">zh_CN</span>
          <span class="version_switcher_placeholder">3.7.3</span>
          <a href="../index.html">文档</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> &#187;</li>
          <li class="nav-item nav-item-3"><a href="asyncio.html" accesskey="U"><code class="docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="coroutines-and-tasks">
<h1>协程与任务<a class="headerlink" href="#coroutines-and-tasks" title="永久链接至标题">¶</a></h1>
<p>本节将简述用于协程与任务的高层级 API。</p>
<div class="contents local topic" id="id1">
<ul class="simple">
<li><a class="reference internal" href="#coroutines" id="id2">协程</a></li>
<li><a class="reference internal" href="#awaitables" id="id3">可等待对象</a></li>
<li><a class="reference internal" href="#running-an-asyncio-program" id="id4">运行 asyncio 程序</a></li>
<li><a class="reference internal" href="#creating-tasks" id="id5">创建任务</a></li>
<li><a class="reference internal" href="#sleeping" id="id6">休眠</a></li>
<li><a class="reference internal" href="#running-tasks-concurrently" id="id7">并发运行任务</a></li>
<li><a class="reference internal" href="#shielding-from-cancellation" id="id8">屏蔽取消操作</a></li>
<li><a class="reference internal" href="#timeouts" id="id9">超时</a></li>
<li><a class="reference internal" href="#waiting-primitives" id="id10">简单等待</a></li>
<li><a class="reference internal" href="#scheduling-from-other-threads" id="id11">来自其他线程的日程安排</a></li>
<li><a class="reference internal" href="#introspection" id="id12">内省</a></li>
<li><a class="reference internal" href="#task-object" id="id13">Task 对象</a></li>
<li><a class="reference internal" href="#generator-based-coroutines" id="id14">基于生成器的协程</a></li>
</ul>
</div>
<div class="section" id="coroutines">
<span id="coroutine"></span><h2><a class="toc-backref" href="#id2">协程</a><a class="headerlink" href="#coroutines" title="永久链接至标题">¶</a></h2>
<p>协程通过 async/await 语法进行声明，是编写异步应用的推荐方式。例如，以下代码段 (需要 Python 3.7+) 打印 &quot;hello&quot;，等待 1 秒，然后打印 &quot;world&quot;:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">asyncio</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;hello&#39;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;world&#39;</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
<span class="go">hello</span>
<span class="go">world</span>
</pre></div>
</div>
<p>注意：简单地调用一个协程并不会将其加入执行日程:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">main</span><span class="p">()</span>
<span class="go">&lt;coroutine object main at 0x1053bb7c8&gt;</span>
</pre></div>
</div>
<p>要真正运行一个协程，asyncio 提供了三种主要机制:</p>
<ul>
<li><p class="first"><a class="reference internal" href="#asyncio.run" title="asyncio.run"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.run()</span></code></a> 函数用来运行最高层级的入口点 &quot;main()&quot; 函数 (参见上面的示例。)</p>
</li>
<li><p class="first">等待一个协程。以下代码段会在等待 1 秒后打印 &quot;hello&quot;，然后 <em>再次</em> 等待 2 秒后打印 &quot;world&quot;:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">say_after</span><span class="p">(</span><span class="n">delay</span><span class="p">,</span> <span class="n">what</span><span class="p">):</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">what</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s2">&quot;started at {time.strftime(&#39;</span><span class="si">%X</span><span class="s2">&#39;)}&quot;</span><span class="p">)</span>

    <span class="k">await</span> <span class="n">say_after</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;hello&#39;</span><span class="p">)</span>
    <span class="k">await</span> <span class="n">say_after</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;world&#39;</span><span class="p">)</span>

    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s2">&quot;finished at {time.strftime(&#39;</span><span class="si">%X</span><span class="s2">&#39;)}&quot;</span><span class="p">)</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<p>预期的输出:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">started</span> <span class="n">at</span> <span class="mi">17</span><span class="p">:</span><span class="mi">13</span><span class="p">:</span><span class="mi">52</span>
<span class="n">hello</span>
<span class="n">world</span>
<span class="n">finished</span> <span class="n">at</span> <span class="mi">17</span><span class="p">:</span><span class="mi">13</span><span class="p">:</span><span class="mi">55</span>
</pre></div>
</div>
</li>
<li><p class="first"><a class="reference internal" href="#asyncio.create_task" title="asyncio.create_task"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.create_task()</span></code></a> 函数用来并发运行作为 asyncio <a class="reference internal" href="#asyncio.Task" title="asyncio.Task"><code class="xref py py-class docutils literal notranslate"><span class="pre">任务</span></code></a> 的多个协程。</p>
<p>让我们修改以上示例，<em>并发</em> 运行两个 <code class="docutils literal notranslate"><span class="pre">say_after</span></code> 协程:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">task1</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span>
        <span class="n">say_after</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">&#39;hello&#39;</span><span class="p">))</span>

    <span class="n">task2</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span>
        <span class="n">say_after</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s1">&#39;world&#39;</span><span class="p">))</span>

    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s2">&quot;started at {time.strftime(&#39;</span><span class="si">%X</span><span class="s2">&#39;)}&quot;</span><span class="p">)</span>

    <span class="c1"># Wait until both tasks are completed (should take</span>
    <span class="c1"># around 2 seconds.)</span>
    <span class="k">await</span> <span class="n">task1</span>
    <span class="k">await</span> <span class="n">task2</span>

    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s2">&quot;finished at {time.strftime(&#39;</span><span class="si">%X</span><span class="s2">&#39;)}&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>注意，预期的输出显示代码段的运行时间比之前快了 1 秒:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">started</span> <span class="n">at</span> <span class="mi">17</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="mi">32</span>
<span class="n">hello</span>
<span class="n">world</span>
<span class="n">finished</span> <span class="n">at</span> <span class="mi">17</span><span class="p">:</span><span class="mi">14</span><span class="p">:</span><span class="mi">34</span>
</pre></div>
</div>
</li>
</ul>
</div>
<div class="section" id="awaitables">
<span id="asyncio-awaitables"></span><h2><a class="toc-backref" href="#id3">可等待对象</a><a class="headerlink" href="#awaitables" title="永久链接至标题">¶</a></h2>
<p>如果一个对象可以在 <a class="reference internal" href="../reference/expressions.html#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a>  语句中使用，那么它就是 <strong>可等待</strong> 对象。许多 asyncio API 都被设计为接受可等待对象。</p>
<p><em>可等待</em> 对象有三种主要类型: <strong>协程</strong>, <strong>任务</strong> 和 <strong>Future</strong>.</p>
<p class="rubric">协程</p>
<p>Python 协程属于 <em>可等待</em> 对象，因此可以在其他协程中被等待:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">nested</span><span class="p">():</span>
    <span class="k">return</span> <span class="mi">42</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Nothing happens if we just call &quot;nested()&quot;.</span>
    <span class="c1"># A coroutine object is created but not awaited,</span>
    <span class="c1"># so it *won&#39;t run at all*.</span>
    <span class="n">nested</span><span class="p">()</span>

    <span class="c1"># Let&#39;s do it differently now and await it:</span>
    <span class="nb">print</span><span class="p">(</span><span class="k">await</span> <span class="n">nested</span><span class="p">())</span>  <span class="c1"># will print &quot;42&quot;.</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition important">
<p class="first admonition-title">重要</p>
<p>在本文档中 &quot;协程&quot; 可用来表示两个紧密关联的概念:</p>
<ul class="last simple">
<li><em>协程函数</em>: 定义形式为 <a class="reference internal" href="../reference/compound_stmts.html#async-def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code></a> 的函数;</li>
<li><em>协程对象</em>: 调用 <em>协程函数</em> 所返回的对象。</li>
</ul>
</div>
<p>asyncio 也支持旧式的 <a class="reference internal" href="#asyncio-generator-based-coro"><span class="std std-ref">基于生成器的</span></a> 协程。</p>
<p class="rubric">任务</p>
<p><em>任务</em> 被用来设置日程以便 <em>并发</em> 执行协程。</p>
<p>当一个协程通过 <a class="reference internal" href="#asyncio.create_task" title="asyncio.create_task"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.create_task()</span></code></a> 等函数被打包为一个 <em>任务</em>，该协程将自动排入日程准备立即运行:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">nested</span><span class="p">():</span>
    <span class="k">return</span> <span class="mi">42</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Schedule nested() to run soon concurrently</span>
    <span class="c1"># with &quot;main()&quot;.</span>
    <span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">nested</span><span class="p">())</span>

    <span class="c1"># &quot;task&quot; can now be used to cancel &quot;nested()&quot;, or</span>
    <span class="c1"># can simply be awaited to wait until it is complete:</span>
    <span class="k">await</span> <span class="n">task</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<p class="rubric">Future 对象</p>
<p><a class="reference internal" href="asyncio-future.html#asyncio.Future" title="asyncio.Future"><code class="xref py py-class docutils literal notranslate"><span class="pre">Future</span></code></a> 是一种特殊的 <strong>低层级</strong> 可等待对象，表示一个异步操作的 <strong>最终结果</strong>。</p>
<p>当一个 Future 对象 <em>被等待</em>，这意味着协程将保持等待直到该 Future 对象在其他地方操作完毕。</p>
<p>在 asyncio 中需要 Future 对象以便允许通过 async/await 使用基于回调的代码。</p>
<p>通常情况下 <strong>没有必要</strong> 在应用层级的代码中创建 Future 对象。</p>
<p>Future 对象有时会由库和某些 asyncio API 暴露给用户，用作可等待对象:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="k">await</span> <span class="n">function_that_returns_a_future_object</span><span class="p">()</span>

    <span class="c1"># this is also valid:</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span>
        <span class="n">function_that_returns_a_future_object</span><span class="p">(),</span>
        <span class="n">some_python_coroutine</span><span class="p">()</span>
    <span class="p">)</span>
</pre></div>
</div>
<p>一个很好的返回对象的低层级函数的示例是 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.run_in_executor" title="asyncio.loop.run_in_executor"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.run_in_executor()</span></code></a>。</p>
</div>
<div class="section" id="running-an-asyncio-program">
<h2><a class="toc-backref" href="#id4">运行 asyncio 程序</a><a class="headerlink" href="#running-an-asyncio-program" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.run">
<code class="descclassname">asyncio.</code><code class="descname">run</code><span class="sig-paren">(</span><em>coro</em>, <em>*</em>, <em>debug=False</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.run" title="永久链接至目标">¶</a></dt>
<dd><p>此函数运行传入的协程，负责管理 asyncio 事件循环并 <em>完结异步生成器</em>。</p>
<p>当有其他 asyncio 事件循环在同一线程中运行时，此函数不能被调用。</p>
<p>如果 <em>debug</em> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，事件循环将以调试模式运行。</p>
<p>此函数总是会创建一个新的事件循环并在结束时关闭之。它应当被用作  asyncio 程序的主入口点，理想情况下应当只被调用一次。</p>
<div class="versionadded">
<p><span class="versionmodified">3.7 新版功能: </span><strong>重要:</strong> 此函数是在 Python 3.7 中加入 asyncio 模块，处于 <a class="reference internal" href="../glossary.html#term-provisional-api"><span class="xref std std-term">暂定基准状态</span></a>。</p>
</div>
</dd></dl>

</div>
<div class="section" id="creating-tasks">
<h2><a class="toc-backref" href="#id5">创建任务</a><a class="headerlink" href="#creating-tasks" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.create_task">
<code class="descclassname">asyncio.</code><code class="descname">create_task</code><span class="sig-paren">(</span><em>coro</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.create_task" title="永久链接至目标">¶</a></dt>
<dd><p>将 <em>coro</em> <a class="reference internal" href="#coroutine"><span class="std std-ref">协程</span></a> 打包为一个 <a class="reference internal" href="#asyncio.Task" title="asyncio.Task"><code class="xref py py-class docutils literal notranslate"><span class="pre">Task</span></code></a> 排入日程准备执行。返回 Task 对象。</p>
<p>该任务会在 <a class="reference internal" href="asyncio-eventloop.html#asyncio.get_running_loop" title="asyncio.get_running_loop"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_running_loop()</span></code></a> 返回的循环中执行，如果当前线程没有在运行的循环则会引发 <a class="reference internal" href="exceptions.html#RuntimeError" title="RuntimeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">RuntimeError</span></code></a>。</p>
<p>此函数 <strong>在 Python 3.7 中被加入</strong>。在 Python 3.7 之前，可以改用低层级的 <a class="reference internal" href="asyncio-future.html#asyncio.ensure_future" title="asyncio.ensure_future"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.ensure_future()</span></code></a> 函数。</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">coro</span><span class="p">():</span>
    <span class="o">...</span>

<span class="c1"># In Python 3.7+</span>
<span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">coro</span><span class="p">())</span>
<span class="o">...</span>

<span class="c1"># This works in all Python versions but is less readable</span>
<span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">ensure_future</span><span class="p">(</span><span class="n">coro</span><span class="p">())</span>
<span class="o">...</span>
</pre></div>
</div>
<div class="versionadded">
<p><span class="versionmodified">3.7 新版功能.</span></p>
</div>
</dd></dl>

</div>
<div class="section" id="sleeping">
<h2><a class="toc-backref" href="#id6">休眠</a><a class="headerlink" href="#sleeping" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.sleep">
<em class="property">coroutine </em><code class="descclassname">asyncio.</code><code class="descname">sleep</code><span class="sig-paren">(</span><em>delay</em>, <em>result=None</em>, <em>*</em>, <em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.sleep" title="永久链接至目标">¶</a></dt>
<dd><p>阻塞 <em>delay</em> 指定的秒数。</p>
<p>如果指定了 <em>result</em>，则当协程完成时将其返回给调用者。</p>
<p><code class="docutils literal notranslate"><span class="pre">sleep()</span></code> 总是会挂起当前任务，以允许其他任务运行。</p>
<p><em>loop</em> 参数已弃用，计划在 Python 3.10 中移除。</p>
<p id="asyncio-example-sleep">以下协程示例运行 5 秒，每秒显示一次当前日期:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">datetime</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">display_date</span><span class="p">():</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
    <span class="n">end_time</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="mf">5.0</span>
    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">())</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">loop</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">end_time</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">display_date</span><span class="p">())</span>
</pre></div>
</div>
</dd></dl>

</div>
<div class="section" id="running-tasks-concurrently">
<h2><a class="toc-backref" href="#id7">并发运行任务</a><a class="headerlink" href="#running-tasks-concurrently" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.gather">
<em class="property">awaitable </em><code class="descclassname">asyncio.</code><code class="descname">gather</code><span class="sig-paren">(</span><em>*aws</em>, <em>loop=None</em>, <em>return_exceptions=False</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.gather" title="永久链接至目标">¶</a></dt>
<dd><p><em>并发</em> 运行 <em>aws</em> 序列中的 <a class="reference internal" href="#asyncio-awaitables"><span class="std std-ref">可等待对象</span></a>。</p>
<p>如果 <em>aws</em> 中的某个可等待对象为协程，它将自动作为一个任务加入日程。</p>
<p>如果所有可等待对象都成功完成，结果将是一个由所有返回值聚合而成的列表。结果值的顺序与 <em>aws</em> 中可等待对象的顺序一致。</p>
<p>如果 <em>return_exceptions</em> 为 <code class="docutils literal notranslate"><span class="pre">False</span></code> (默认)，所引发的首个异常会立即传播给等待 <code class="docutils literal notranslate"><span class="pre">gather()</span></code> 的任务。<em>aws</em> 序列中的其他可等待对象 <strong>不会被取消</strong> 并将继续运行。</p>
<p>如果 <em>return_exceptions</em> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，异常会和成功的结果一样处理，并聚合至结果列表。</p>
<p>如果 <code class="docutils literal notranslate"><span class="pre">gather()</span></code> <em>被取消</em>，所有被提交 (尚未完成) 的可等待对象也会 <em>被取消</em>。</p>
<p>如果 <em>aws</em> 序列中的任一 Task 或 Future 对象 <em>被取消</em>，它将被当作引发了 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 一样处理 -- 在此情况下 <code class="docutils literal notranslate"><span class="pre">gather()</span></code> 调用 <strong>不会</strong> 被取消。这是为了防止一个已提交的 Task/Future 被取消导致其他 Tasks/Future 也被取消。</p>
<p id="asyncio-example-gather">示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
    <span class="n">f</span> <span class="o">=</span> <span class="mi">1</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">number</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s2">&quot;Task </span><span class="si">{name}</span><span class="s2">: Compute factorial(</span><span class="si">{i}</span><span class="s2">)...&quot;</span><span class="p">)</span>
        <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
        <span class="n">f</span> <span class="o">*=</span> <span class="n">i</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s2">&quot;Task </span><span class="si">{name}</span><span class="s2">: factorial(</span><span class="si">{number}</span><span class="s2">) = </span><span class="si">{f}</span><span class="s2">&quot;</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Schedule three calls *concurrently*:</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">gather</span><span class="p">(</span>
        <span class="n">factorial</span><span class="p">(</span><span class="s2">&quot;A&quot;</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span>
        <span class="n">factorial</span><span class="p">(</span><span class="s2">&quot;B&quot;</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span>
        <span class="n">factorial</span><span class="p">(</span><span class="s2">&quot;C&quot;</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span>
    <span class="p">)</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>

<span class="c1"># Expected output:</span>
<span class="c1">#</span>
<span class="c1">#     Task A: Compute factorial(2)...</span>
<span class="c1">#     Task B: Compute factorial(2)...</span>
<span class="c1">#     Task C: Compute factorial(2)...</span>
<span class="c1">#     Task A: factorial(2) = 2</span>
<span class="c1">#     Task B: Compute factorial(3)...</span>
<span class="c1">#     Task C: Compute factorial(3)...</span>
<span class="c1">#     Task B: factorial(3) = 6</span>
<span class="c1">#     Task C: Compute factorial(4)...</span>
<span class="c1">#     Task C: factorial(4) = 24</span>
</pre></div>
</div>
<div class="versionchanged">
<p><span class="versionmodified">在 3.7 版更改: </span>如果 <em>gather</em> 本身被取消，则无论 <em>return_exceptions</em> 取值为何，消息都会被传播。</p>
</div>
</dd></dl>

</div>
<div class="section" id="shielding-from-cancellation">
<h2><a class="toc-backref" href="#id8">屏蔽取消操作</a><a class="headerlink" href="#shielding-from-cancellation" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.shield">
<em class="property">awaitable </em><code class="descclassname">asyncio.</code><code class="descname">shield</code><span class="sig-paren">(</span><em>aw</em>, <em>*</em>, <em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.shield" title="永久链接至目标">¶</a></dt>
<dd><p>保护一个 <a class="reference internal" href="#asyncio-awaitables"><span class="std std-ref">可等待对象</span></a> 防止其被 <a class="reference internal" href="#asyncio.Task.cancel" title="asyncio.Task.cancel"><code class="xref py py-meth docutils literal notranslate"><span class="pre">取消</span></code></a>。</p>
<p>如果 <em>aw</em> 是一个协程，它将自动作为任务加入日程。</p>
<p>以下语句:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">res</span> <span class="o">=</span> <span class="k">await</span> <span class="n">shield</span><span class="p">(</span><span class="n">something</span><span class="p">())</span>
</pre></div>
</div>
<p>相当于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">res</span> <span class="o">=</span> <span class="k">await</span> <span class="n">something</span><span class="p">()</span>
</pre></div>
</div>
<p><em>不同之处</em> 在于如果包含它的协程被取消，在 <code class="docutils literal notranslate"><span class="pre">something()</span></code> 中运行的任务不会被取消。从 <code class="docutils literal notranslate"><span class="pre">something()</span></code> 的角度看来，取消操作并没有发生。然而其调用者已被取消，因此 &quot;await&quot; 表达式仍然会引发 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a>。</p>
<p>如果通过其他方式取消 <code class="docutils literal notranslate"><span class="pre">something()</span></code> (例如在其内部操作) 则 <code class="docutils literal notranslate"><span class="pre">shield()</span></code> 也会取消。</p>
<p>如果希望完全忽略取消操作 (不推荐) 则 <code class="docutils literal notranslate"><span class="pre">shield()</span></code> 函数需要配合一个 try/except 代码段，如下所示:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="n">res</span> <span class="o">=</span> <span class="k">await</span> <span class="n">shield</span><span class="p">(</span><span class="n">something</span><span class="p">())</span>
<span class="k">except</span> <span class="n">CancelledError</span><span class="p">:</span>
    <span class="n">res</span> <span class="o">=</span> <span class="kc">None</span>
</pre></div>
</div>
</dd></dl>

</div>
<div class="section" id="timeouts">
<h2><a class="toc-backref" href="#id9">超时</a><a class="headerlink" href="#timeouts" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.wait_for">
<em class="property">coroutine </em><code class="descclassname">asyncio.</code><code class="descname">wait_for</code><span class="sig-paren">(</span><em>aw</em>, <em>timeout</em>, <em>*</em>, <em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.wait_for" title="永久链接至目标">¶</a></dt>
<dd><p>等待 <em>aw</em> <a class="reference internal" href="#asyncio-awaitables"><span class="std std-ref">可等待对象</span></a> 完成，指定 timeout 秒数后超时。</p>
<p>如果 <em>aw</em> 是一个协程，它将自动作为任务加入日程。</p>
<p><em>timeout</em> 可以为 <code class="docutils literal notranslate"><span class="pre">None</span></code>，也可以为 float 或 int 型数值表示的等待秒数。如果 <em>timeout</em> 为 <code class="docutils literal notranslate"><span class="pre">None</span></code>，则等待直到完成。</p>
<p>如果发生超时，任务将取消并引发 <a class="reference internal" href="asyncio-exceptions.html#asyncio.TimeoutError" title="asyncio.TimeoutError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">asyncio.TimeoutError</span></code></a>.</p>
<p>要避免任务 <a class="reference internal" href="#asyncio.Task.cancel" title="asyncio.Task.cancel"><code class="xref py py-meth docutils literal notranslate"><span class="pre">取消</span></code></a>，可以加上 <a class="reference internal" href="#asyncio.shield" title="asyncio.shield"><code class="xref py py-func docutils literal notranslate"><span class="pre">shield()</span></code></a>。</p>
<p>函数将等待直到目标对象确实被取消，所以总等待时间可能超过 <em>timeout</em> 指定的秒数。</p>
<p>如果等待被取消，则 <em>aw</em> 指定的对象也会被取消。</p>
<p><em>loop</em> 参数已弃用，计划在 Python 3.10 中移除。</p>
<p id="asyncio-example-waitfor">示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">eternity</span><span class="p">():</span>
    <span class="c1"># Sleep for one hour</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3600</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;yay!&#39;</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Wait for at most 1 second</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait_for</span><span class="p">(</span><span class="n">eternity</span><span class="p">(),</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">1.0</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;timeout!&#39;</span><span class="p">)</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>

<span class="c1"># Expected output:</span>
<span class="c1">#</span>
<span class="c1">#     timeout!</span>
</pre></div>
</div>
<div class="versionchanged">
<p><span class="versionmodified">在 3.7 版更改: </span>当 <em>aw</em> 因超时被取消，<code class="docutils literal notranslate"><span class="pre">wait_for</span></code> 会等待 <em>aw</em> 被取消。之前版本则将立即引发 <a class="reference internal" href="asyncio-exceptions.html#asyncio.TimeoutError" title="asyncio.TimeoutError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">asyncio.TimeoutError</span></code></a>。</p>
</div>
</dd></dl>

</div>
<div class="section" id="waiting-primitives">
<h2><a class="toc-backref" href="#id10">简单等待</a><a class="headerlink" href="#waiting-primitives" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.wait">
<em class="property">coroutine </em><code class="descclassname">asyncio.</code><code class="descname">wait</code><span class="sig-paren">(</span><em>aws</em>, <em>*</em>, <em>loop=None</em>, <em>timeout=None</em>, <em>return_when=ALL_COMPLETED</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.wait" title="永久链接至目标">¶</a></dt>
<dd><p>并发运行 <em>aws</em> 指定的 <a class="reference internal" href="#asyncio-awaitables"><span class="std std-ref">可等待对象</span></a> 并阻塞线程直到满足 <em>return_when</em> 指定的条件。</p>
<p>如果 <em>aws</em> 中的某个可等待对象为协程，它将自动作为任务加入日程。直接向 <code class="docutils literal notranslate"><span class="pre">wait()</span></code> 传入协程对象已弃用，因为这会导致 <a class="reference internal" href="#asyncio-example-wait-coroutine"><span class="std std-ref">令人迷惑的行为</span></a>。</p>
<p>返回两个 Task/Future 集合: <code class="docutils literal notranslate"><span class="pre">(done,</span> <span class="pre">pending)</span></code>。</p>
<p>用法:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">done</span><span class="p">,</span> <span class="n">pending</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">aws</span><span class="p">)</span>
</pre></div>
</div>
<p><em>loop</em> 参数已弃用，计划在 Python 3.10 中移除。</p>
<p>如指定 <em>timeout</em> (float 或 int 类型) 则它将被用于控制返回之前等待的最长秒数。</p>
<p>请注意此函数不会引发 <a class="reference internal" href="asyncio-exceptions.html#asyncio.TimeoutError" title="asyncio.TimeoutError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">asyncio.TimeoutError</span></code></a>。当超时发生时，未完成的 Future 或 Task 将在指定秒数后被返回。</p>
<p><em>return_when</em> 指定此函数应在何时返回。它必须为以下常数之一:</p>
<table border="1" class="docutils">
<colgroup>
<col width="42%" />
<col width="58%" />
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">常数</th>
<th class="head">描述</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td><code class="xref py py-const docutils literal notranslate"><span class="pre">FIRST_COMPLETED</span></code></td>
<td>函数将在任意可等待对象结束或取消时返回。</td>
</tr>
<tr class="row-odd"><td><code class="xref py py-const docutils literal notranslate"><span class="pre">FIRST_EXCEPTION</span></code></td>
<td>函数将在任意可等待对象因引发异常而结束时返回。当没有引发任何异常时它就相当于 <code class="xref py py-const docutils literal notranslate"><span class="pre">ALL_COMPLETED</span></code>。</td>
</tr>
<tr class="row-even"><td><code class="xref py py-const docutils literal notranslate"><span class="pre">ALL_COMPLETED</span></code></td>
<td>函数将在所有可等待对象结束或取消时返回。</td>
</tr>
</tbody>
</table>
<p>与 <a class="reference internal" href="#asyncio.wait_for" title="asyncio.wait_for"><code class="xref py py-func docutils literal notranslate"><span class="pre">wait_for()</span></code></a> 不同，<code class="docutils literal notranslate"><span class="pre">wait()</span></code> 在超时发生时不会取消可等待对象。</p>
<div class="admonition note" id="asyncio-example-wait-coroutine">
<p class="first admonition-title">注解</p>
<p><code class="docutils literal notranslate"><span class="pre">wait()</span></code> 会自动将协程作为任务加入日程，以后将以 <code class="docutils literal notranslate"><span class="pre">(done,</span> <span class="pre">pending)</span></code> 集合形式返回显式创建的任务对象。因此以下代码并不会有预期的行为:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
    <span class="k">return</span> <span class="mi">42</span>

<span class="n">coro</span> <span class="o">=</span> <span class="n">foo</span><span class="p">()</span>
<span class="n">done</span><span class="p">,</span> <span class="n">pending</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait</span><span class="p">({</span><span class="n">coro</span><span class="p">})</span>

<span class="k">if</span> <span class="n">coro</span> <span class="ow">in</span> <span class="n">done</span><span class="p">:</span>
    <span class="c1"># This branch will never be run!</span>
</pre></div>
</div>
<p>以上代码段的修正方法如下:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
    <span class="k">return</span> <span class="mi">42</span>

<span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">foo</span><span class="p">())</span>
<span class="n">done</span><span class="p">,</span> <span class="n">pending</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">wait</span><span class="p">({</span><span class="n">task</span><span class="p">})</span>

<span class="k">if</span> <span class="n">task</span> <span class="ow">in</span> <span class="n">done</span><span class="p">:</span>
    <span class="c1"># Everything will work as expected now.</span>
</pre></div>
</div>
<p class="last">直接向 <code class="docutils literal notranslate"><span class="pre">wait()</span></code> 传入协程对象的方式已弃用。</p>
</div>
</dd></dl>

<dl class="function">
<dt id="asyncio.as_completed">
<code class="descclassname">asyncio.</code><code class="descname">as_completed</code><span class="sig-paren">(</span><em>aws</em>, <em>*</em>, <em>loop=None</em>, <em>timeout=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.as_completed" title="永久链接至目标">¶</a></dt>
<dd><p>&nbsp;并发地运行 <em>aws</em> 集合中的 <a class="reference internal" href="#asyncio-awaitables"><span class="std std-ref">可等待对象</span></a>。返回一个 <a class="reference internal" href="asyncio-future.html#asyncio.Future" title="asyncio.Future"><code class="xref py py-class docutils literal notranslate"><span class="pre">Future</span></code></a> 对象的迭代器。返回的每个 Future 对象代表来自剩余可等待对象集合的最早结果。</p>
<p>如果在所有 Future 对象完成前发生超时则将引发 <a class="reference internal" href="asyncio-exceptions.html#asyncio.TimeoutError" title="asyncio.TimeoutError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">asyncio.TimeoutError</span></code></a>。</p>
<p>示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">as_completed</span><span class="p">(</span><span class="n">aws</span><span class="p">):</span>
    <span class="n">earliest_result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">f</span>
    <span class="c1"># ...</span>
</pre></div>
</div>
</dd></dl>

</div>
<div class="section" id="scheduling-from-other-threads">
<h2><a class="toc-backref" href="#id11">来自其他线程的日程安排</a><a class="headerlink" href="#scheduling-from-other-threads" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.run_coroutine_threadsafe">
<code class="descclassname">asyncio.</code><code class="descname">run_coroutine_threadsafe</code><span class="sig-paren">(</span><em>coro</em>, <em>loop</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.run_coroutine_threadsafe" title="永久链接至目标">¶</a></dt>
<dd><p>向指定事件循环提交一个协程。线程安全。</p>
<p>返回一个 <a class="reference internal" href="concurrent.futures.html#concurrent.futures.Future" title="concurrent.futures.Future"><code class="xref py py-class docutils literal notranslate"><span class="pre">concurrent.futures.Future</span></code></a> 以等待来自其他 OS 线程的结果。</p>
<p>此函数应该从另一个 OS 线程中调用，而非事件循环运行所在线程。示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Create a coroutine</span>
<span class="n">coro</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">result</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>

<span class="c1"># Submit the coroutine to a given loop</span>
<span class="n">future</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">run_coroutine_threadsafe</span><span class="p">(</span><span class="n">coro</span><span class="p">,</span> <span class="n">loop</span><span class="p">)</span>

<span class="c1"># Wait for the result with an optional timeout argument</span>
<span class="k">assert</span> <span class="n">future</span><span class="o">.</span><span class="n">result</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span>
</pre></div>
</div>
<p>如果在协程内产生了异常，将会通知返回的 Future 对象。它也可被用来取消事件循环中的任务:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
    <span class="n">result</span> <span class="o">=</span> <span class="n">future</span><span class="o">.</span><span class="n">result</span><span class="p">(</span><span class="n">timeout</span><span class="p">)</span>
<span class="k">except</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;The coroutine took too long, cancelling the task...&#39;</span><span class="p">)</span>
    <span class="n">future</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s1">&#39;The coroutine raised an exception: </span><span class="si">{exc!r}</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">f</span><span class="s1">&#39;The coroutine returned: </span><span class="si">{result!r}</span><span class="s1">&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>查看 <a class="reference internal" href="asyncio-dev.html#asyncio-multithreading"><span class="std std-ref">并发和多线程</span></a> 章节的文档。</p>
<p>不同与其他 asyncio 函数，此函数要求显式地传入 <em>loop</em> 参数。</p>
<div class="versionadded">
<p><span class="versionmodified">3.5.1 新版功能.</span></p>
</div>
</dd></dl>

</div>
<div class="section" id="introspection">
<h2><a class="toc-backref" href="#id12">内省</a><a class="headerlink" href="#introspection" title="永久链接至标题">¶</a></h2>
<dl class="function">
<dt id="asyncio.current_task">
<code class="descclassname">asyncio.</code><code class="descname">current_task</code><span class="sig-paren">(</span><em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.current_task" title="永久链接至目标">¶</a></dt>
<dd><p>返回当前运行的 <a class="reference internal" href="#asyncio.Task" title="asyncio.Task"><code class="xref py py-class docutils literal notranslate"><span class="pre">Task</span></code></a> 实例，如果没有正在运行的任务则返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
<p>如果 <em>loop</em> 为 <code class="docutils literal notranslate"><span class="pre">None</span></code> 则会使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.get_running_loop" title="asyncio.get_running_loop"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_running_loop()</span></code></a> 获取当前事件循环。</p>
<div class="versionadded">
<p><span class="versionmodified">3.7 新版功能.</span></p>
</div>
</dd></dl>

<dl class="function">
<dt id="asyncio.all_tasks">
<code class="descclassname">asyncio.</code><code class="descname">all_tasks</code><span class="sig-paren">(</span><em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.all_tasks" title="永久链接至目标">¶</a></dt>
<dd><p>返回事件循环所运行的未完成的 <a class="reference internal" href="#asyncio.Task" title="asyncio.Task"><code class="xref py py-class docutils literal notranslate"><span class="pre">Task</span></code></a> 对象的集合。</p>
<p>如果 <em>loop</em> 为 <code class="docutils literal notranslate"><span class="pre">None</span></code>，则会使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.get_running_loop" title="asyncio.get_running_loop"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_running_loop()</span></code></a> 获取当前事件循环。</p>
<div class="versionadded">
<p><span class="versionmodified">3.7 新版功能.</span></p>
</div>
</dd></dl>

</div>
<div class="section" id="task-object">
<h2><a class="toc-backref" href="#id13">Task 对象</a><a class="headerlink" href="#task-object" title="永久链接至标题">¶</a></h2>
<dl class="class">
<dt id="asyncio.Task">
<em class="property">class </em><code class="descclassname">asyncio.</code><code class="descname">Task</code><span class="sig-paren">(</span><em>coro</em>, <em>*</em>, <em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task" title="永久链接至目标">¶</a></dt>
<dd><p>一个与 <a class="reference internal" href="asyncio-future.html#asyncio.Future" title="asyncio.Future"><code class="xref py py-class docutils literal notranslate"><span class="pre">Future</span> <span class="pre">类似</span></code></a> 的对象，可运行 Python <a class="reference internal" href="#coroutine"><span class="std std-ref">协程</span></a>。非线程安全。</p>
<p>Task 对象被用来在事件循环中运行协程。如果一个协程在等待一个 Future 对象，Task 对象会挂起该协程的执行并等待该 Future 对象完成。当该 Future 对象 <em>完成</em>，被打包的协程将恢复执行。</p>
<p>事件循环使用协同日程调度: 一个事件循环每次运行一个 Task 对象。而一个 Task 对象会等待一个 Future 对象完成，该事件循环会运行其他 Task、回调或执行 IO 操作。</p>
<p>使用高层级的 <a class="reference internal" href="#asyncio.create_task" title="asyncio.create_task"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.create_task()</span></code></a> 函数来创建 Task 对象，也可用低层级的 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_task" title="asyncio.loop.create_task"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_task()</span></code></a> 或 <a class="reference internal" href="asyncio-future.html#asyncio.ensure_future" title="asyncio.ensure_future"><code class="xref py py-func docutils literal notranslate"><span class="pre">ensure_future()</span></code></a> 函数。不建议手动实例化 Task 对象。</p>
<p>要取消一个正在运行的 Task 对象可使用 <a class="reference internal" href="#asyncio.Task.cancel" title="asyncio.Task.cancel"><code class="xref py py-meth docutils literal notranslate"><span class="pre">cancel()</span></code></a> 方法。调用此方法将使该 Task 对象抛出一个 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 异常给打包的协程。如果取消期间一个协程正在等待一个 Future 对象，该 Future 对象也将被取消。</p>
<p><a class="reference internal" href="#asyncio.Task.cancelled" title="asyncio.Task.cancelled"><code class="xref py py-meth docutils literal notranslate"><span class="pre">cancelled()</span></code></a> 可被用来检测 Task 对象是否被取消。如果打包的协程没有抑制 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 异常并且确实被取消，该方法将返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p><a class="reference internal" href="#asyncio.Task" title="asyncio.Task"><code class="xref py py-class docutils literal notranslate"><span class="pre">asyncio.Task</span></code></a> 从 <a class="reference internal" href="asyncio-future.html#asyncio.Future" title="asyncio.Future"><code class="xref py py-class docutils literal notranslate"><span class="pre">Future</span></code></a> 继承了其除 <a class="reference internal" href="asyncio-future.html#asyncio.Future.set_result" title="asyncio.Future.set_result"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Future.set_result()</span></code></a> 和 <a class="reference internal" href="asyncio-future.html#asyncio.Future.set_exception" title="asyncio.Future.set_exception"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Future.set_exception()</span></code></a> 以外的所有 API。</p>
<p>Task 对象支持 <a class="reference internal" href="contextvars.html#module-contextvars" title="contextvars: Context Variables"><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextvars</span></code></a> 模块。当一个 Task 对象被创建，它将复制当前上下文，然后在复制的上下文中运行其协程。</p>
<div class="versionchanged">
<p><span class="versionmodified">在 3.7 版更改: </span>加入对 <a class="reference internal" href="contextvars.html#module-contextvars" title="contextvars: Context Variables"><code class="xref py py-mod docutils literal notranslate"><span class="pre">contextvars</span></code></a> 模块的支持。</p>
</div>
<dl class="method">
<dt id="asyncio.Task.cancel">
<code class="descname">cancel</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.cancel" title="永久链接至目标">¶</a></dt>
<dd><p>请求取消 Task 对象。</p>
<p>这将安排在下一轮事件循环中抛出一个 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 异常给被封包的协程。</p>
<p>协程在之后有机会进行清理甚至使用 <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> ... ... <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">CancelledError</span></code> ... <a class="reference internal" href="../reference/compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 代码块抑制异常来拒绝请求。不同于 <a class="reference internal" href="asyncio-future.html#asyncio.Future.cancel" title="asyncio.Future.cancel"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Future.cancel()</span></code></a>，<a class="reference internal" href="#asyncio.Task.cancel" title="asyncio.Task.cancel"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Task.cancel()</span></code></a> 不保证 Task 会被取消，虽然抑制完全取消并不常见，也很不鼓励这样做。</p>
<p id="asyncio-example-task-cancel">以下示例演示了协程是如何拦截取消请求的:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">cancel_me</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;cancel_me(): before sleep&#39;</span><span class="p">)</span>

    <span class="k">try</span><span class="p">:</span>
        <span class="c1"># Wait for 1 hour</span>
        <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3600</span><span class="p">)</span>
    <span class="k">except</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">CancelledError</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;cancel_me(): cancel sleep&#39;</span><span class="p">)</span>
        <span class="k">raise</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;cancel_me(): after sleep&#39;</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="c1"># Create a &quot;cancel_me&quot; Task</span>
    <span class="n">task</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">cancel_me</span><span class="p">())</span>

    <span class="c1"># Wait for 1 second</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>

    <span class="n">task</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">await</span> <span class="n">task</span>
    <span class="k">except</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">CancelledError</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;main(): cancel_me is cancelled now&quot;</span><span class="p">)</span>

<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>

<span class="c1"># Expected output:</span>
<span class="c1">#</span>
<span class="c1">#     cancel_me(): before sleep</span>
<span class="c1">#     cancel_me(): cancel sleep</span>
<span class="c1">#     cancel_me(): after sleep</span>
<span class="c1">#     main(): cancel_me is cancelled now</span>
</pre></div>
</div>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.cancelled">
<code class="descname">cancelled</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.cancelled" title="永久链接至目标">¶</a></dt>
<dd><p>如果 Task 对象 <em>被取消</em> 则返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p>当使用 <a class="reference internal" href="#asyncio.Task.cancel" title="asyncio.Task.cancel"><code class="xref py py-meth docutils literal notranslate"><span class="pre">cancel()</span></code></a> 发出取消请求时 Task 会被 <em>取消</em>，其封包的协程将传播被抛入的 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 异常。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.done">
<code class="descname">done</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.done" title="永久链接至目标">¶</a></dt>
<dd><p>如果 Task 对象 <em>已完成</em> 则返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p>当 Task 所封包的协程返回一个值、引发一个异常或 Task 本身被取消时，则会被认为 <em>已完成</em>。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.result">
<code class="descname">result</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.result" title="永久链接至目标">¶</a></dt>
<dd><p>返回 Task 的结果。</p>
<p>如果 Task 对象 <em>已完成</em>，其封包的协程的结果会被返回 (或者当协程引发异常时，该异常会被重新引发。)</p>
<p>如果 Task 对象 <em>被取消</em>，此方法会引发一个 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 异常。</p>
<p>如果 Task 对象的结果还不可用，此方法会引发一个 <a class="reference internal" href="asyncio-exceptions.html#asyncio.InvalidStateError" title="asyncio.InvalidStateError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">InvalidStateError</span></code></a> 异常。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.exception">
<code class="descname">exception</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.exception" title="永久链接至目标">¶</a></dt>
<dd><p>返回 Task 对象的异常。</p>
<p>如果所封包的协程引发了一个异常，该异常将被返回。如果所封包的协程正常返回则该方法将返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
<p>如果 Task 对象 <em>被取消</em>，此方法会引发一个 <a class="reference internal" href="asyncio-exceptions.html#asyncio.CancelledError" title="asyncio.CancelledError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CancelledError</span></code></a> 异常。</p>
<p>如果 Task 对象尚未 <em>完成</em>，此方法将引发一个 <a class="reference internal" href="asyncio-exceptions.html#asyncio.InvalidStateError" title="asyncio.InvalidStateError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">InvalidStateError</span></code></a> 异常。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.add_done_callback">
<code class="descname">add_done_callback</code><span class="sig-paren">(</span><em>callback</em>, <em>*</em>, <em>context=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.add_done_callback" title="永久链接至目标">¶</a></dt>
<dd><p>添加一个回调，将在 Task 对象 <em>完成</em> 时被运行。</p>
<p>此方法应该仅在低层级的基于回调的代码中使用。</p>
<p>要了解更多细节请查看 <a class="reference internal" href="asyncio-future.html#asyncio.Future.add_done_callback" title="asyncio.Future.add_done_callback"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Future.add_done_callback()</span></code></a> 的文档。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.remove_done_callback">
<code class="descname">remove_done_callback</code><span class="sig-paren">(</span><em>callback</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.remove_done_callback" title="永久链接至目标">¶</a></dt>
<dd><p>从回调列表中移除 <em>callback</em> 指定的回调。</p>
<p>此方法应该仅在低层级的基于回调的代码中使用。</p>
<p>要了解更多细节请查看 <a class="reference internal" href="asyncio-future.html#asyncio.Future.remove_done_callback" title="asyncio.Future.remove_done_callback"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Future.remove_done_callback()</span></code></a> 的文档。</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.get_stack">
<code class="descname">get_stack</code><span class="sig-paren">(</span><em>*</em>, <em>limit=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.get_stack" title="永久链接至目标">¶</a></dt>
<dd><p>返回此 Task 对象的栈框架列表。</p>
<p>如果所封包的协程未完成，这将返回其挂起所在的栈。如果协程已成功完成或被取消，这将返回一个空列表。如果协程被一个异常终止，这将返回回溯框架列表。</p>
<p>框架总是从按从旧到新排序。</p>
<p>每个被挂起的协程只返回一个栈框架。</p>
<p>可选的 <em>limit</em> 参数指定返回框架的数量上限；默认返回所有框架。返回列表的顺序要看是返回一个栈还是一个回溯：栈返回最新的框架，回溯返回最旧的框架。(这与 traceback 模块的行为保持一致。)</p>
</dd></dl>

<dl class="method">
<dt id="asyncio.Task.print_stack">
<code class="descname">print_stack</code><span class="sig-paren">(</span><em>*</em>, <em>limit=None</em>, <em>file=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.print_stack" title="永久链接至目标">¶</a></dt>
<dd><p>打印此 Task 对象的栈或回溯。</p>
<p>此方法产生的输出类似于 traceback 模块通过 <a class="reference internal" href="#asyncio.Task.get_stack" title="asyncio.Task.get_stack"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_stack()</span></code></a> 所获取的框架。</p>
<p><em>limit</em> 参数会直接传递给 <a class="reference internal" href="#asyncio.Task.get_stack" title="asyncio.Task.get_stack"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_stack()</span></code></a>。</p>
<p><em>file</em> 参数是输出所写入的 I/O 流；默认情况下输出会写入 <a class="reference internal" href="sys.html#sys.stderr" title="sys.stderr"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stderr</span></code></a>。</p>
</dd></dl>

<dl class="classmethod">
<dt id="asyncio.Task.all_tasks">
<em class="property">classmethod </em><code class="descname">all_tasks</code><span class="sig-paren">(</span><em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.all_tasks" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个事件循环中所有任务的集合。</p>
<p>默认情况下将返回当前事件循环中所有任务。如果 <em>loop</em> 为 <code class="docutils literal notranslate"><span class="pre">None</span></code>，则会使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.get_event_loop" title="asyncio.get_event_loop"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_event_loop()</span></code></a> 函数来获取当前事件循环。</p>
<p>此方法 <strong>已弃用</strong> 并将在 Python 3.9 中移除。请改用 <a class="reference internal" href="#asyncio.all_tasks" title="asyncio.all_tasks"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.all_tasks()</span></code></a> 函数。</p>
</dd></dl>

<dl class="classmethod">
<dt id="asyncio.Task.current_task">
<em class="property">classmethod </em><code class="descname">current_task</code><span class="sig-paren">(</span><em>loop=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Task.current_task" title="永久链接至目标">¶</a></dt>
<dd><p>返回当前运行任务或 <code class="docutils literal notranslate"><span class="pre">None</span></code>。</p>
<p>如果 <em>loop</em> 为 <code class="docutils literal notranslate"><span class="pre">None</span></code>，则会使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.get_event_loop" title="asyncio.get_event_loop"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_event_loop()</span></code></a> 函数来获取当前事件循环。</p>
<p>此方法 <strong>已弃用</strong> 并将在 Python 3.9 中移除。请改用 <a class="reference internal" href="#asyncio.current_task" title="asyncio.current_task"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.current_task()</span></code></a> 函数。</p>
</dd></dl>

</dd></dl>

</div>
<div class="section" id="generator-based-coroutines">
<span id="asyncio-generator-based-coro"></span><h2><a class="toc-backref" href="#id14">基于生成器的协程</a><a class="headerlink" href="#generator-based-coroutines" title="永久链接至标题">¶</a></h2>
<div class="admonition note">
<p class="first admonition-title">注解</p>
<p class="last">对基于生成器的协程的支持 <strong>已弃用</strong> 并计划在 Python 3.10 中移除。</p>
</div>
<p>基于生成器的协程是 async/await 语法的前身。它们是使用 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 语句创建的 Python 生成器，可以等待 Future 和其他协程。</p>
<p>基于生成器的协程应该使用 <a class="reference internal" href="#asyncio.coroutine" title="asyncio.coroutine"><code class="xref py py-func docutils literal notranslate"><span class="pre">&#64;asyncio.coroutine</span></code></a> 装饰，虽然这并非强制。</p>
<dl class="function">
<dt id="asyncio.coroutine">
<code class="descclassname">&#64;</code><code class="descclassname">asyncio.</code><code class="descname">coroutine</code><a class="headerlink" href="#asyncio.coroutine" title="永久链接至目标">¶</a></dt>
<dd><p>用来标记基于生成器的协程的装饰器。</p>
<p>此装饰器使得旧式的基于生成器的协程能与 async/await 代码相兼容:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@asyncio</span><span class="o">.</span><span class="n">coroutine</span>
<span class="k">def</span> <span class="nf">old_style_coroutine</span><span class="p">():</span>
    <span class="k">yield from</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="k">await</span> <span class="n">old_style_coroutine</span><span class="p">()</span>
</pre></div>
</div>
<p>此装饰器 <strong>已弃用</strong> 并计划觉得 Python 3.10 中移除。</p>
<p>此装饰器不应该被用于 <a class="reference internal" href="../reference/compound_stmts.html#async-def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code></a> 协程。</p>
</dd></dl>

<dl class="function">
<dt id="asyncio.iscoroutine">
<code class="descclassname">asyncio.</code><code class="descname">iscoroutine</code><span class="sig-paren">(</span><em>obj</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.iscoroutine" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <em>obj</em> 是一个 <a class="reference internal" href="#coroutine"><span class="std std-ref">协程对象</span></a> 则返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p>此方法不同于 <a class="reference internal" href="inspect.html#inspect.iscoroutine" title="inspect.iscoroutine"><code class="xref py py-func docutils literal notranslate"><span class="pre">inspect.iscoroutine()</span></code></a> 因为它对基于生成器的协程返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
</dd></dl>

<dl class="function">
<dt id="asyncio.iscoroutinefunction">
<code class="descclassname">asyncio.</code><code class="descname">iscoroutinefunction</code><span class="sig-paren">(</span><em>func</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.iscoroutinefunction" title="永久链接至目标">¶</a></dt>
<dd><p>如果 <em>func</em> 是一个 <a class="reference internal" href="#coroutine"><span class="std std-ref">协程函数</span></a> 则返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p>此方法不同于 <a class="reference internal" href="inspect.html#inspect.iscoroutinefunction" title="inspect.iscoroutinefunction"><code class="xref py py-func docutils literal notranslate"><span class="pre">inspect.iscoroutinefunction()</span></code></a> 因为它对以 <a class="reference internal" href="#asyncio.coroutine" title="asyncio.coroutine"><code class="xref py py-func docutils literal notranslate"><span class="pre">&#64;coroutine</span></code></a> 装饰的基于生成器的协程函数返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
</dd></dl>

</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">协程与任务</a><ul>
<li><a class="reference internal" href="#coroutines">协程</a></li>
<li><a class="reference internal" href="#awaitables">可等待对象</a></li>
<li><a class="reference internal" href="#running-an-asyncio-program">运行 asyncio 程序</a></li>
<li><a class="reference internal" href="#creating-tasks">创建任务</a></li>
<li><a class="reference internal" href="#sleeping">休眠</a></li>
<li><a class="reference internal" href="#running-tasks-concurrently">并发运行任务</a></li>
<li><a class="reference internal" href="#shielding-from-cancellation">屏蔽取消操作</a></li>
<li><a class="reference internal" href="#timeouts">超时</a></li>
<li><a class="reference internal" href="#waiting-primitives">简单等待</a></li>
<li><a class="reference internal" href="#scheduling-from-other-threads">来自其他线程的日程安排</a></li>
<li><a class="reference internal" href="#introspection">内省</a></li>
<li><a class="reference internal" href="#task-object">Task 对象</a></li>
<li><a class="reference internal" href="#generator-based-coroutines">基于生成器的协程</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="asyncio.html"
                        title="上一章"><code class="docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="asyncio-stream.html"
                        title="下一章">流</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/library/asyncio-task.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="asyncio-stream.html" title="流"
             >下一页</a> |</li>
        <li class="right" >
          <a href="asyncio.html" title="asyncio --- 异步 I/O"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <span class="language_switcher_placeholder">zh_CN</span>
          <span class="version_switcher_placeholder">3.7.3</span>
          <a href="../index.html">文档</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
          <li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> &#187;</li>
          <li class="nav-item nav-item-3"><a href="asyncio.html" ><code class="docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2019, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 4月 09, 2019.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>1.8.4 创建。
    </div>

  </body>
</html>